/*
 * @Description: 入口文件
 * @Autor: xiaohuihui
 * @Date: 2022-11-28 16:24:58
 * @LastEditors: xiaohuihui
 * @LastEditTime: 2022-12-26 14:28:11
 */
const express = require("express");
const cors = require("cors");
const userRouter = require("./router/user");
const userInfoRouter = require("./router/userInfo");
const joi = require("joi");
// 导入配置文件
const config = require("./config");
// 解析 token 的中间件
const expressJWT = require("express-jwt");

const app = express();

// 封装一个函数 优化 res.send() 代码
app.use((req, res, next) => {
    // 默认为status 为失败状态 data可以返回数据
    res.cc = (message, status = 400, data) => {
        // res.status(status).send({
        res.send({
            status,
            message: message instanceof Error ? message.message : message,
            data,
        });
    };
    next();
});

// 配置跨域
app.use(cors());
// 配置解析表单数据的中间件 json
app.use(express.json());
// x-www-form-urlencoded
app.use(express.urlencoded({ extended: false }));

// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(
    expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/api\//] })
);

app.use("/api", userRouter);

app.use("/my", userInfoRouter);

// 测试
app.get("/api", (req, res) => {
    res.send("请求根路径");
});

// 处理错误中间件，防止服务器崩溃
app.use((err, req, res, next) => {
    // 数据验证失败
    if (err instanceof joi.ValidationError) return res.cc(err);
    // 捕获身份认证失败的错误
    if (err.name === "UnauthorizedError") return res.cc("身份认证失败！");
    let message = err.message ?? "Internal Server Error!";
    let statusCode = err.statusCode ?? 500;
    res.status(statusCode).json({
        message,
        statusCode,
    });
});

app.listen(3030, () => {
    console.log("服务运行在 http://localhost:3030");
});
